package 剑指offer;

import java.util.Stack;

/**
 * @description:
 * @author: ywk
 * @date: 2020-10-28
 */
public class 表达式求值 {
    public static void main(String[] args) {
        System.out.println(solve("(3+4)*(5+(2-3))"));

    }
    //"1+2" ，3  ，，"3+2*3*4-1" 26

    /**
     * 代码中的类名、方法名、参数名已经指定，请勿修改，直接返回方法规定的值即可
     * 返回表达式的值
     *
     * @param s string字符串 待计算的表达式
     * @return int整型
     */
    public static int solve(String s) {
        // write code here
        Stack<Character> op = new Stack<>();
        StringBuilder sb = new StringBuilder();
        String strOp = "+-*/#()";
        //(2*(3-4))*5
        for (int i = 0; i < s.length(); i++) {
            char ele = s.charAt(i);
            if (!strOp.contains(String.valueOf(ele))) {
                sb.append("#");
                while (i < s.length() && !strOp.contains(String.valueOf(s.charAt(i)))) {
                    sb.append(s.charAt(i));
                    i++;
                }
                i--;
            } else {
                if (ele == ')') {
                    while (op.peek() != '(') {
                        sb.append(op.pop());
                    }
                    op.pop();
                } else if (op.isEmpty() || ele == '(' || !isBigger(op.peek(), ele)) {
                    op.push(ele);
                } else {
                    while (!op.isEmpty() && isBigger((op.peek()), ele)) {
                        sb.append(op.pop());
                    }
                    op.push(ele);
                }
            }

        }
        while (!op.isEmpty()) {
            sb.append(op.pop());
        }
        Stack<String> stack = new Stack<>();
        String str = sb.toString();
        for (int i = 0; i < str.length(); i++) {
            if (str.charAt(i) == '#') {
                int j = i + 1;
                while (!strOp.contains(String.valueOf(str.charAt(j)))) {
                    j++;
                }
                stack.push(str.substring(i + 1, j));
                i = j - 1;
            } else if (strOp.contains(String.valueOf(str.charAt(i)))) {
                int next = Integer.parseInt(stack.pop());
                int pre = Integer.parseInt(stack.pop());
                int sum = 0;
                switch (str.charAt(i)) {
                    case '*':
                        sum = pre * next;
                        break;
                    case '/':
                        sum = pre / next;
                        break;
                    case '-':
                        sum = pre - next;
                        break;
                    case '+':
                        sum = pre + next;
                        break;
                }
                stack.push(String.valueOf(sum));
            }


        }
        return Integer.parseInt(stack.pop());
    }

    public static boolean isBigger(char a, char b) {
        if ((a == '-' || a == '+') && (b == '-' || b == '+')) {
            return true;
        }
        if (a == '(' && b == '(') {
            return false;
        }
        if ((a == '*' || a == '/') && (b == '*' || b == '/')) {
            return true;
        }
        return (a == '*' || a == '/') && (b == '-' || b == '+');

    }
}
